﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DnsChanger;
using System.IO;
using DnsChanger.Config;
using DnsChanger.Exceptions;
using System.Collections.ObjectModel;

namespace DnsChangerConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            // no args so print usage
            if (args.Length == 0)
            {
                PrintUsage();
                return;
            }

            DnsServerElement server = DnsChangerConfiguration.Instance.DnsServers.Find(args[0]);
            if (server != null)
            {
                TrySetDnsServers(server);
                return;
            }

            switch (args[0].ToLower())
            {
                case "m":
                case "manual":
                    if (args.Length == 1)
                    {
                        // no servers given!
                        Console.WriteLine("Manual setting requires a comma seperated list of servers");
                        PrintUsage();
                        return;
                    }

                    DnsServerElement manualServer = new DnsServerElement
                    {
                        Name = "Manual",
                        ConfigServers = args[1]
                    };
                    TrySetDnsServers(manualServer);
                    return;

                case "get":
                case "getdns":
                case "current":
                    List<string> dnsServers = DnsHelper.GetDnsServers();
                    Console.WriteLine("The current list of Dns servers is:");
                    string serverCsv = dnsServers.AsCsv();
                    Console.WriteLine(serverCsv);
                    return;

                case "backup":
                    List<string> currentDnsServers = DnsHelper.GetDnsServers();
                    DnsServerElement backupElement = DnsChangerConfiguration.Instance.DnsServers["Restore"];
                    if (backupElement == null)
                    {
                        backupElement = new DnsServerElement();
                        backupElement.Name = "Restore";
                        backupElement.ConfigArgs = "restore";
                    }
                    backupElement.ConfigServers = currentDnsServers.AsCsv();
                    backupElement.Info = currentDnsServers.AsCsv();
                    DnsChangerConfiguration.Instance.DnsServers["Restore"] = backupElement;
                    DnsChangerConfiguration.Instance.Save();
                    Console.WriteLine("Saved current settings as 'Restore'.");
                    PrintUsage();
                    return;

                case "restore":
                    // if a backup has been taken restore will be in the DnsChangerConfiguration so we won't reach this case.
                    Console.WriteLine("There is no backup to restore.");
                    Console.WriteLine("Saved current settings as 'Restore'.");
                    PrintUsage();
                    return;

                default:
                    PrintUsage();
                    return;
            }
        }

        private static void TrySetDnsServers(DnsServerElement server)
        {
            try
            {
                DnsHelper.SetDnsServers(server.Servers);
            }
            catch (DnsServerSearchOrderException ex)
            {
                Console.Write("Failed to change servers. ErrorCode: {0}", ex.Code);
                return;
            }
        }

        private static void PrintUsage()
        {
            string exe = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
            Console.WriteLine("Usage:");
            Console.WriteLine("{0} <arg1> [<arg2>]", exe);
            Console.WriteLine("  where <arg1> is one of the following.", exe);

            string format = "    <arg1> = {0} to '{1}'";

            Console.WriteLine(format, "m,manual", "insert the comma seperated list of servers from <arg2>");
            Console.WriteLine(format, "get,getdns,current", "print the current servers to the screen");
            Console.WriteLine(format, "backup", "save the current settings so they can be restored");
            Console.WriteLine(format, "restore", "restore the backed up settings");

            format += " ({2})";
            foreach (DnsServerElement dnsServer in DnsChangerConfiguration.Instance.DnsServers)
            {
                Console.WriteLine(format, dnsServer.ConfigArgs, dnsServer.Name, dnsServer.Info);
            }
        }
    }
}
